package com.example.blog_app.constants;

import org.hibernate.HibernateException;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.usertype.UserType;

import java.io.Serializable;
import java.sql.*;

public class PgStringArrayType implements UserType {

    protected static final int[] SQL_TYPES = {Types.ARRAY};


    /**
     * 返回UserType所映射字段的SQL类型（java.sql.Types)
     * 返回类型为int[]，其中包含了映射个字段的SQL类型代码
     * (UserType可以映射到一个或者多个字段)
     * @return
     */


    @Override
    public Object assemble(Serializable cached, Object owner) throws HibernateException {
        return null;
    }

    @Override
    public Object deepCopy(Object value) throws HibernateException {
        return value;
    }

    @SuppressWarnings("unchecked")
    @Override
    public Serializable disassemble(Object value) throws HibernateException {
        return null;
    }


    /**
     * 自定义数据类型的比对方法
     * 此方法将用作脏数据检查，参数x、y分别为数据的两个副本
     * 如果equals方法返回false,则Hibernate将认为数据发生变化,并将变化更新到数据库表中
     */
    @Override
    public boolean equals(Object x, Object y) throws HibernateException {

        if (x == null) {
            return y == null;
        }
        return x.equals(y);
        //return Arrays.equals(x, y);
    }

    @Override
    public int hashCode(Object x) throws HibernateException {
        return x.hashCode();
    }

    @Override
    public Object nullSafeGet(ResultSet resultSet,
                              String[] names,
                              SharedSessionContractImplementor sharedSessionContractImplementor,
                              Object o) throws HibernateException, SQLException {
        if (resultSet.wasNull()) {
            return null;
        }
        if (resultSet.getArray(names[0]) == null) {
            return new String[0];
        }

        String[] array = (String[])resultSet.getArray(names[0]).getArray();
        return array;
    }

    @Override
    public void nullSafeSet(PreparedStatement preparedStatement, Object value, int index, SharedSessionContractImplementor sharedSessionContractImplementor) throws HibernateException, SQLException {
        Connection connection = preparedStatement.getConnection();
        if (value == null) {
            preparedStatement.setNull(index, SQL_TYPES[0]);
        } else {
            String[] castObject = (String[]) value;
            Array array = connection.createArrayOf("text",  castObject);
            preparedStatement.setArray(index, array);
        }
    }

    @Override
    public boolean isMutable() {
        return true;
    }

    @Override
    public Object replace(Object original, Object target, Object owner) throws HibernateException {
        return original;
    }


    /**
     * UserType.nullSafeGet()所返回的自定义数据类型
     */
    @Override
    public final Class returnedClass() {
        return String[].class;
    }

    /**
     * 返回UserType所映射字段的SQL类型（java.sql.Types)
     * 返回类型为int[]，其中包含了映射个字段的SQL类型代码
     * (UserType可以映射到一个或者多个字段)
     */
    @Override
    public int[] sqlTypes() {
        return new int[]{Types.ARRAY};
    }
}
